package com.canaan.quality.service.quality.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.canaan.business.common.enums.quality.QualityTypeEnum;
import com.canaan.business.common.enums.quality.QualityValueTypeEnum;
import com.canaan.business.domain.basic.WmsProduct;
import com.canaan.business.domain.quality.QualityItem;
import com.canaan.business.service.basic.IWmsProductService;
import com.canaan.business.service.quality.IQualityItemService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.TableNoUtil;
import com.canaan.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import com.canaan.business.mapper.quality.ProductQualityItemMapper;
import com.canaan.business.domain.quality.ProductQualityItem;
import com.canaan.business.service.quality.IProductQualityItemService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 物料质检项Service业务层处理
 *
 * @author ruoyi
 * @date 2023-02-03
 */
@Service
public class ProductQualityItemServiceImpl implements IProductQualityItemService {
    @Resource
    private ProductQualityItemMapper productQualityItemMapper;
    @Resource
    private IWmsProductService wmsProductService;
    @Resource
    private IQualityItemService qualityItemService;

    /**
     * 查询物料质检项
     *
     * @param id 物料质检项主键
     * @return 物料质检项
     */
    @Override
    public ProductQualityItem selectProductQualityItemById(Long id) {
        return productQualityItemMapper.selectProductQualityItemById(id);
    }

    /**
     * 查询物料质检项列表
     *
     * @param productQualityItem 物料质检项
     * @return 物料质检项
     */
    @Override
    public List<ProductQualityItem> selectProductQualityItemList(ProductQualityItem productQualityItem) {
        return productQualityItemMapper.selectProductQualityItemList(productQualityItem);
    }

    /**
     * 新增物料质检项
     *
     * @param productQualityItem 物料质检项
     * @return 结果
     */
    @Override
    public int insertProductQualityItem(ProductQualityItem productQualityItem) {
        if(StringUtils.isBlank(productQualityItem.getNo())){
            productQualityItem.setNo(TableNoUtil.getNo(ProductQualityItem.class));
        }
        productQualityItem.setCreateBy(SecurityUtils.getUsername());
        productQualityItem.setCreateTime(DateUtils.getNowDate());
        return productQualityItemMapper.insertProductQualityItem(productQualityItem);
    }

    /**
     * 批量新增物料质检项
     *
     * @param productQualityItemList 物料质检项列表
     * @return 结果
     */
    @Override
    public int batchInsertProductQualityItem(List<ProductQualityItem> productQualityItemList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (ProductQualityItem productQualityItem : productQualityItemList){
            if(StringUtils.isBlank(productQualityItem.getNo())){
                productQualityItem.setNo(TableNoUtil.getNo(ProductQualityItem.class));
            }
            productQualityItem.setCreateBy(username);
            productQualityItem.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<productQualityItemList.size();) {
            int endIndex = i+500;
            if (endIndex > productQualityItemList.size()) {
                endIndex = productQualityItemList.size();
            }
            insertNum = insertNum + productQualityItemMapper.batchInsertProductQualityItem(productQualityItemList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改物料质检项
     *
     * @param productQualityItem 物料质检项
     * @return 结果
     */
    @Override
    public int updateProductQualityItem(ProductQualityItem productQualityItem) {
        productQualityItem.setUpdateBy(SecurityUtils.getUsername());
        productQualityItem.setUpdateTime(DateUtils.getNowDate());
        return productQualityItemMapper.updateProductQualityItem(productQualityItem);
    }

    /**
     * 批量修改物料质检项
     *
     * @param productQualityItemList 物料质检项列表
     * @return 结果
     */
    @Override
    public int batchUpdateProductQualityItem(List<ProductQualityItem> productQualityItemList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (ProductQualityItem productQualityItem : productQualityItemList){
            productQualityItem.setUpdateBy(username);
            productQualityItem.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i=0; i<productQualityItemList.size();) {
            int endIndex = i+500;
            if (endIndex > productQualityItemList.size()) {
                endIndex = productQualityItemList.size();
            }
            updateNum = updateNum + productQualityItemMapper.batchUpdateProductQualityItem(productQualityItemList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除物料质检项
     *
     * @param ids 需要删除的物料质检项主键集合
     * @return 结果
     */
    @Override
    public int deleteProductQualityItemByIds(Long[] ids) {
        return productQualityItemMapper.deleteProductQualityItemByIds(ids);
    }

    /**
     * 删除物料质检项信息
     *
     * @param id 物料质检项主键
     * @return 结果
     */
    @Override
    public int deleteProductQualityItemById(Long id) {
        return productQualityItemMapper.deleteProductQualityItemById(id);
    }

    /**
     * 查询物料质检项
     *
     * @param no 编号
     * @return 物料质检项
     */
    @Override
    public ProductQualityItem selectProductQualityItemByNo(String no) {
        return productQualityItemMapper.selectProductQualityItemByNo(no);
    }

    /**
     * 批量删除物料质检项
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deleteProductQualityItemByNos(String[] nos) {
        return productQualityItemMapper.deleteProductQualityItemByNos(nos);
    }

    /**
     * 删除物料质检项信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deleteProductQualityItemByNo(String no) {
        return productQualityItemMapper.deleteProductQualityItemByNo(no);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importData(List<ProductQualityItem> fileDataList) {
        if (StringUtils.isNull(fileDataList) || fileDataList.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        // 查询文档中存在的所有物料编码，用于校验物料是否存在
        List<String> fileProductNos = fileDataList.stream().map(ProductQualityItem::getProductNo).collect(Collectors.toList());
        WmsProduct searchProduct = new WmsProduct();
        searchProduct.setProductNos(fileProductNos);
        List<WmsProduct> fileProductList = this.wmsProductService.selectWmsProductList(searchProduct);
        Map<String,String> fileProductNoAndNameMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(fileProductList)){
            fileProductNoAndNameMap = fileProductList.stream().collect(Collectors.toMap(WmsProduct::getProductNo, WmsProduct::getProductName, (key1, key2) -> key2));
        }

        // 查询文档中存在的所有质检项名称，校验质检项是否存在
        List<String> fileItemNames = fileDataList.stream().map(ProductQualityItem::getItemName).collect(Collectors.toList());
        QualityItem searchItem = new QualityItem();
        searchItem.setNames(fileItemNames);
        List<QualityItem> fileItemList = this.qualityItemService.selectQualityItemList(searchItem);
        Map<String,QualityItem> fileItemNameMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(fileItemList)){
            fileItemNameMap = fileItemList.stream().collect(Collectors.toMap(QualityItem::getName, Function.identity(), (key1, key2) -> key2));
        }

        // 根据文档中的物料编码，查询出现有的质检项
        ProductQualityItem searchProductItem = new ProductQualityItem();
        searchProductItem.setProductNos(fileProductNos);
        List<ProductQualityItem> oldItemList = this.selectProductQualityItemList(searchProductItem);
        Map<String,List<ProductQualityItem>> oldItemMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(oldItemList)){
            oldItemMap = oldItemList.stream().collect(Collectors.groupingBy(ProductQualityItem::getProductNo));
        }

        // 循环校验必填以及文档内是否存在重复数据
        for (int i = 0; i < fileDataList.size(); i++) {
            ProductQualityItem fileEntity = fileDataList.get(i);
            int rowNum = i + 2;
            if (StringUtils.isEmpty(fileEntity.getProductNo())) {
                failureNum++;
                failureMsg.append("第" + rowNum + "行物料编码不能为空");
                break;
            }
            String productName = fileProductNoAndNameMap.get(fileEntity.getProductNo());
            if (StringUtils.isEmpty(productName)){
                failureNum++;
                failureMsg.append("第" + rowNum + "行物料编码对应物料不存在，请修改后提交");
                break;
            }
            if (StringUtils.isEmpty(fileEntity.getItemName())) {
                failureNum++;
                failureMsg.append("第" + rowNum + "行质检项名称不能为空");
                break;
            }
            QualityItem qualityItem = fileItemNameMap.get(fileEntity.getItemName());
            if (qualityItem == null){
                failureNum++;
                failureMsg.append("第" + rowNum + "行质检项名称对应质检项不存在，请修改后提交");
                break;
            }
            // 判断质检项是否重复
            List<ProductQualityItem> oldProductItemList = oldItemMap.get(fileEntity.getProductNo());
            if (!CollectionUtils.isEmpty(oldProductItemList)){
                List<String> oldItemNames = oldProductItemList.stream().map(ProductQualityItem::getItemName).collect(Collectors.toList());
                if (oldItemNames.contains(fileEntity.getItemName())){
                    failureNum++;
                    failureMsg.append("第" + rowNum + "行物料对应质检项已存在，请修改");
                    break;
                }else {
                    oldProductItemList.add(fileEntity);
                }
            }
            fileEntity.setValueType(qualityItem.getValueType());
            fileEntity.setItemNo(qualityItem.getNo());
            // 判断标准上下限
            if (QualityValueTypeEnum.RANGE.getCode().equals(fileEntity.getValueType())){
                if (fileEntity.getLowerLimitValue() == null || fileEntity.getUpperLimitValue() == null){
                    failureNum++;
                    failureMsg.append("第" + rowNum + "行质检项值类型为范围值，标准上下限不能为空");
                    break;
                }
                if (fileEntity.getLowerLimitValue().compareTo(fileEntity.getUpperLimitValue()) > 0){
                    failureNum++;
                    failureMsg.append("第" + rowNum + "行标准下限不能高于标准上限");
                    break;
                }
            }
            if (StringUtils.isEmpty(fileEntity.getMethod())){
                fileEntity.setMethod(qualityItem.getMethod());
            }

        }
        if (failureNum > 0) {
            failureMsg.insert(0, "导入失败！");
            throw new ServiceException(failureMsg.toString());
        } else {
            int addCount = this.batchInsertProductQualityItem(fileDataList);
            successMsg.insert(0, "导入成功！共新增 " + addCount + " 条数据");
        }
        return successMsg.toString();
    }

    @Override
    public List<ProductQualityItem> selectByPnAndQualityType(String productNo, String qualityType) {
        ProductQualityItem query = new ProductQualityItem();
        query.setProductNo(productNo);
        query.setQualityType(qualityType);
        return this.selectProductQualityItemList(query);
    }

    /**
     * 是否出货检
     * @param productNo
     * @return
     */
    @Override
    public boolean isOqc(String productNo) {
        List<ProductQualityItem> qualityItemList = selectByPnAndQualityType(productNo, QualityTypeEnum.OQC.getCode());
        if (CollectionUtil.isNotEmpty(qualityItemList)){
            return true;
        }else{
            return false;
        }
    }
    /**
     * 是否来料检
     * @param productNo
     * @return
     */
    @Override
    public boolean isIqc(String productNo) {
        List<ProductQualityItem> qualityItemList = selectByPnAndQualityType(productNo, QualityTypeEnum.IQC.getCode());
        if (CollectionUtil.isNotEmpty(qualityItemList)){
            return true;
        }else{
            return false;
        }
    }


}
